package de.akabahn.ebd.stw.zdxfc.prs.fst.impair;

import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.BIT0;
import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.FAHRSTRASSE_IC;
import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.MELDER_SIGNAL_CV5;
import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.MELDER_TASTE_IC;
import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.SIGNAL_CV13;
import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.SIGNAL_CV51;
import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.SIGNAL_CV52;
import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.SIGNAL_CV53;
import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.SIGNAL_CV6;
import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.VERSCHLUSS;
import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.WEICHE_1;
import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.WEICHE_12;
import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.WEICHE_2;
import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.WEICHE_5;
import static de.akabahn.ebd.stw.zdxfc.prs.ZDXFCConstants.WEICHE_6;
import de.akabahn.ebd.comm.dbd.DBDParameter;
import de.akabahn.ebd.dbd.SwitchPosition;
import de.akabahn.ebd.dbd.impl.DBDSignalF;
import de.akabahn.ebd.stw.zdxfc.prs.ZDXFCMain;
import de.akabahn.ebd.stw.zdxfc.prs.fst.FahrStrasse;

/**
 * Fahrstrasse <code>IC</code><br>
 * Start: Signal CV5 (CV52)<br>
 * Ziel: Gleis 16 / 17<br>
 * <br>
 * Fahrstrassen Weichen:<br>
 * <ol>
 * <li>Weiche 1, Rechtslage (Flankenschutz)</li>
 * <li>Weiche 2, Rechtslage</li>
 * <li>Weiche 5, Rechtslage</li>
 * <li>Weiche 6, Linkslage</li>
 * <li>Weiche 12, Rechtslage</li>
 * </ol>
 * <br>
 * Fahrstrassen Gleise:<br>
 * <ol>
 * <li>-</li>
 * </ol>
 * <br>
 * Fahrstrassen Signale:<br>
 * <ol>
 * <li>Signal Cv51, kein manueller Haltfall</li>
 * <li>Signal Cv52, Startsignal, kein manueller Haltfall</li>
 * <li>Signal Cv53, kein manueller Haltfall</li>
 * <li>Signal Cv6, Lichtschutz</li>
 * <li>Signal Cv13, Lichtschutz</li>
 * </ol>
 * 
 * @author Peter Eimann
 * @since 1.0
 * @version 1.2
 */
public class FahrStrasseIC extends FahrStrasse {

	/**
	 * Initialisierung mit ID <code>IC</code> und DBD-Name des Tastenmelders <code>S31TICS</code>
	 * 
	 * @param main Referenz auf die Hauptklasse
	 */
	public FahrStrasseIC(ZDXFCMain main) {
		super(FAHRSTRASSE_IC, MELDER_TASTE_IC, main, SIGNAL_CV52);

		fstWeichen = new FstWeiche[] {
				new FstWeiche(WEICHE_1, SwitchPosition.RIGHT, true),
				new FstWeiche(WEICHE_2, SwitchPosition.RIGHT, false),
				new FstWeiche(WEICHE_5, SwitchPosition.RIGHT, false),
				new FstWeiche(WEICHE_6, SwitchPosition.LEFT, false),
				new FstWeiche(WEICHE_12, SwitchPosition.RIGHT, false)
		};
		
		fstGleise = new FstGleis[] {};
		
		fstSignale = new FstSignal[] {
				new FstSignal(SIGNAL_CV51, true),
				new FstSignal(SIGNAL_CV52, true),
				new FstSignal(SIGNAL_CV53, true),
				new FstSignal(SIGNAL_CV6, false),
				new FstSignal(SIGNAL_CV13, false)
		};
	}

	/**
	 * Wird die Fahrstrasse verschlossen, wird der Verschlussmelder des Signals mit Dauerlicht ausgeleuchtet,
	 * anderenfalls wird die Ausleuchtung geloescht.
	 */
	@Override
	public void setVerschlossen(boolean verschlossen) {
		super.setVerschlossen(verschlossen);

		if (verschlossen) {
			main.getDbd().set(MELDER_SIGNAL_CV5[VERSCHLUSS], BIT0);
		} else {
			main.getDbd().set(MELDER_SIGNAL_CV5[VERSCHLUSS], 0);
		}
	}

	/**
	 * Verschluss:<br>
	 * <ul>
	 * <li>Sofortiger Verschluss der Fahrstrasse (EPa)</li>
	 * </ul>
	 * <br>
	 * Startsignal CV52:<br>
	 * <ul>
	 * <li>Fahrstrassen-ID <code>IC</code></li>
	 * <li>Signalbegriff <code>(M)</code></li>
	 * </ul>
	 */
	@Override
	public void einstellenProcess() {
		setVerschlossen(true);

		main.getSignal(SIGNAL_CV52).setFahrStrassenId(id);
		main.getSignal(SIGNAL_CV52).stellen(DBDSignalF.MC);
	}

	/**
	 * Ueberpruefte Bedingungen:<br>
	 * <ol>
	 * <li>Aufloesezeit muss kleiner gleich 0 sein</li>
	 * <li>Haltfall Signal <code>CV52</code></li>
	 * </ol>
	 * <br>
	 * Aktionen bei erfolgreicher Pruefung:<br>
	 * <ul>
	 * <li><i>keine</i></li>
	 * </ul>
	 */
	@Override
	public boolean aufloeseBedinungenOk() {
		return main.getSignal(SIGNAL_CV52).isHalt() && getAufloeseZeit() <= 0;
	}

	/**
	 * Ueberwachte Elemente:<br>
	 * <ol>
	 * <li>Weiche 2</li>
	 * <li>Weiche 12</li>
	 * </ol>
	 */
	@Override
	public void onChangeBesetzung(DBDParameter dbd) {
		if (dbd.getId().equals(WEICHE_2)) {
			onChangeWeiche2();
		} else if (dbd.getId().equals(WEICHE_12)) {
			onChangeWeiche12();
		}
	}

	/**
	 * Ueberwachung der Weiche 2:<br>
	 * Aktionen beim Besetzen:<br>
	 * <ol>
	 * <li>Aufloesung Weiche 2 vorbereiten</li>
	 * <li>Haltfall Startsignale</li>
	 * </ol>
	 * <br>
	 * Aktionen beim Freifahren:<br>
	 * <ol>
	 * <li>Verschluss der Fahrstrasse aufloesen</li>
	 * <li>Ausleuchtung Tastenmelder der Fahrstrasse loeschen</li>
	 * <li>Flankenschutz <code>Weiche 1</code> aufloesen</li>
	 * <li>Weiche 2, Weiche 5 und Weiche 6 inaktiv setzen</li>
	 * </ol> 
	 */
	private void onChangeWeiche2() {
		if (main.getWeiche(WEICHE_2).isBesetzt()) {
			main.getWeiche(WEICHE_2).setAufloesenVorbereiten(true);
			haltfallStartsignale();
		} else {
			if (main.getWeiche(WEICHE_2).isAufloesenVorbereiten() && main.getWeiche(WEICHE_12).isBesetzt()) {
				main.getWeiche(WEICHE_2).setAufloesenVorbereiten(false);
				main.getWeiche(WEICHE_2).setAktiv(false);
				main.getWeiche(WEICHE_5).setAktiv(false);
				main.getWeiche(WEICHE_6).setAktiv(false);
				setVerschlossen(false);
				main.getDbd().set(getTastenMelderId(), 0);
				main.getWeiche(WEICHE_1).setFlankenSchutz(false);
			}
		}
	}

	/**
	 * Ueberwachung der Weiche 12:<br>
	 * Aktionen beim Besetzen:<br>
	 * <ol>
	 * <li>Aufloesung Weiche 12 vorbereiten</li>
	 * <li>Haltfall Startsignale</li>
	 * </ol>
	 * <br>
	 * Aktionen beim Freifahren:<br>
	 * <ol>
	 * <li>Fahrstrasse inaktiv setzen</li>
	 * <li>Weiche 12 inaktiv setzen</li>
	 * </ol> 
	 */
	private void onChangeWeiche12() {
		if (main.getWeiche(WEICHE_12).isBesetzt()) {
			main.getWeiche(WEICHE_12).setAufloesenVorbereiten(true);
			haltfallStartsignale();
		} else {
			if (main.getWeiche(WEICHE_12).isAufloesenVorbereiten() && !main.getWeiche(WEICHE_2).isBesetzt()) {
				main.getWeiche(WEICHE_12).setAufloesenVorbereiten(false);
				main.getWeiche(WEICHE_12).setAktiv(false);
				setAktiv(false);
			}
		}
	}
}
